/**
 * 
 */
package boundary.components;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;

import calculator.CoordinateManager;

/**
 * @author davide
 *
 */
public class ActiveImage extends Rectangle
{
    private static final long serialVersionUID = 4052539062877892925L;
    
    Point fakeOrigin;
    boolean isClosed = false;
    
    /**
     * 
     */
    public ActiveImage()
    {
	super(0, 0);
	this.fakeOrigin = new Point(0, 0);
    }

    public void setLocation(int xCoord, int yCoord, int zoomFactor)
    {
	this.fakeOrigin.setLocation(CoordinateManager.absoluteCoord(xCoord, zoomFactor),
		CoordinateManager.absoluteCoord(yCoord, zoomFactor));
	
	super.setLocation(this.fakeOrigin);
    }
    
    public void setLowerBound(int xCoord, int yCoord, int zoomFactor)
    {
	int xp = CoordinateManager.absoluteCoord(xCoord, zoomFactor);
	int yp = CoordinateManager.absoluteCoord(yCoord, zoomFactor);
	
	int size = this.computeWidth(xp, yp);
	
	if(this.fakeOrigin.x > xp) {
	    super.setLocation(this.fakeOrigin.x - size, this.y);
	}
	
	if(this.fakeOrigin.y > yp) {
	    super.setLocation(this.x, this.fakeOrigin.y - size);
	}
	
	super.setSize(size, size);
    }
    
    public void setLowerBoundAndClose(int xCoord, int yCoord, int zoomFactor)
    {
	this.isClosed = true;
	this.setLowerBound(xCoord, yCoord, zoomFactor);
    }
    
    public boolean contains(int xCoord, int yCoord, int zoomFactor)
    {
	return super.contains(CoordinateManager.absoluteCoord(xCoord, zoomFactor),
		CoordinateManager.absoluteCoord(yCoord, zoomFactor));
    }

    public void reset()
    {
	this.setSize(-1, -1);
	this.isClosed = false;
    }
    
    private int computeWidth(int xCoord, int yCoord)
    {
	int value = (Math.abs(xCoord - this.fakeOrigin.x) < Math.abs(yCoord - this.fakeOrigin.y)) ?
		Math.abs(xCoord - this.fakeOrigin.x) : Math.abs(yCoord - this.fakeOrigin.y);
	
	return CoordinateManager.nearestLesserPowerOfTwo(value);
    }
    
    private void drawScaledRectangle(Graphics2D g, int zoomFactor)
    {
	Rectangle viewport = new Rectangle(
		CoordinateManager.relativeCoord(this.x, zoomFactor),
		CoordinateManager.relativeCoord(this.y, zoomFactor), 
		CoordinateManager.relativeCoord(this.width, zoomFactor),
		CoordinateManager.relativeCoord(this.height, zoomFactor));
	
	g.drawRect(viewport.x, viewport.y, viewport.width, viewport.height);
    }
    
    private void drawScaledToolTip(Graphics2D g, int zoomFactor)
    {
	if(this.width > 0 && this.height > 0)
	{
	    g.drawString(this.width + "x" + this.height,
		    CoordinateManager.relativeCoord(this.x + this.width, zoomFactor) + 10,
		    CoordinateManager.relativeCoord(this.y + this.height, zoomFactor) + 10);
	}
    }

    private void paintAsTemporary(Graphics2D g, int zoomFactor)
    {
	float dash[] = { 5.0f };
	
	g.setColor(new Color(0, 0, 0));
	g.setStroke(new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, dash, 0.0f));
	    
	this.drawScaledRectangle(g, zoomFactor);
	this.drawScaledToolTip(g, zoomFactor);
    }
    
    private void paintAsActiveImage(Graphics2D g, int zoomFactor)
    {
	g.setStroke(new BasicStroke(2));
	g.setColor(new Color(255, 0, 255));
	
	this.drawScaledRectangle(g, zoomFactor);
    }
    
    public void paintComponent(Graphics2D g, int zoomFactor)
    {
	if(this.isClosed) {
	    this.paintAsActiveImage(g, zoomFactor);
	}
	
	else {
	    this.paintAsTemporary(g, zoomFactor);
	}
    }
}
